#!/usr/bin/env python
# -*- coding: utf-8 -*-
import cexapi
import datetime
import time
import re
import logging
import math

logging.basicConfig(format='%(asctime)s; %(message)s', filename='trade.log',level=logging.DEBUG)

credentialFile = open('credentials.txt', 'r+')

for line in credentialFile:
        resultLine = re.split(';', line)  
        if resultLine[0]=='hannesh':
            apiUser=resultLine[0]
            apiCred1=resultLine[1]
            apiCred2=resultLine[2]      

demo = cexapi.api(apiUser, apiCred1, apiCred2)

def clearAllorders():
    
    try:
        current_orders = demo.current_orders()
        while current_orders:
            for order in current_orders:
                print order
                demo.cancel_order(order['id'])
                time.sleep(1)
            current_orders = demo.current_orders()
    except:
        print "Exception with Clear Allorders"

def strRound(number,anzStellen):
    return str(round(number,anzStellen))        

def roundStr(numberStr,anzStellen):
    return str(round(float(numberStr),anzStellen))

def putInitalOrderBlock(medBidAsk):
    for i in range(1, securityMargin):
        print "sell order", medBidAsk+(i*abstand)
        print "buy order", medBidAsk-(i*abstand)
        demo.place_order('sell',ghsPkg,medBidAsk+(i*abstand))
        demo.place_order('buy',ghsPkg,medBidAsk-(i*abstand))   
        time.sleep(3)
    
def getFromBal(GHSBTC,avl_orders):
    retVal=0
    try:
        retVal=float(bal[GHSBTC][avl_orders])
    except:
        retVal=0
    return retVal

def strRound(number,anzStellen):
    return str(round(number,anzStellen))

def estimateProfit(diskretDiffSells, diskretDiffBuys, abstand, ghsPkg):
    m=min(diskretDiffSells, diskretDiffBuys)
    return 1000*abstand*ghsPkg*(m+1)*m/2

#clearAllorders()

ticker = demo.ticker()
medBidAsk=(float(ticker['bid'])+float(ticker['ask']))/2
abstand=0.000002
ghsPkg=0.05
normalizeCycles=2
securityMargin=60
satoshi=0.00000001

#putInitalOrderBlock(medBidAsk)

#print "sell order", medBidAsk+(i*abstand)
#demo.place_order('sell',ghsPkg,0.01296831+(70*abstand))

profitReset=0
buyBook=0
sellBook=0
buyAdd=0
sellAdd=0

lastResetMinSellPrice=0
lastResetMaxBuyPrice=0
#newCycle=normalizeCycles
newCycle=2
beginningNormalize=1
while True:
    try:
        print "Status"
        print "-----------------------"
        current_orders = demo.current_orders()
        sortedCurrOrders = sorted(current_orders, key=lambda order: order['price'], reverse=True)
        maxSellPrice=-1
        minSellPrice=100
        maxBuyPrice=-1
        minBuyPrice=100
        sellCount=0
        buyCount=0
                
        ticker = demo.ticker()    
        for order in sortedCurrOrders:  
            if order['type']=='sell':
                sellCount=sellCount+1            
                maxSellPrice=max(float(order['price']),maxSellPrice)           
                minSellPrice=min(float(order['price']),minSellPrice)
            if order['type']=='buy':
                buyCount=buyCount+1            
                maxBuyPrice=max(float(order['price']),maxBuyPrice)
                minBuyPrice=min(float(order['price']),minBuyPrice)        
    
        if minSellPrice==100 and maxBuyPrice>0:
            ticker = demo.ticker()
            leastDiff2SellIndex=math.ceil((float(ticker['ask'])-maxBuyPrice)/abstand)+10
            minSellPrice=maxBuyPrice+(leastDiff2SellIndex*abstand)
            print "place inner sells @",minSellPrice
            demo.place_order('sell',ghsPkg,minSellPrice)
        
        
         
                
        print "sellCount=",sellCount, "buyCount=",buyCount
        print "minSellPrice=",minSellPrice, "maxBuyPrice=",maxBuyPrice, "diff=",round((minSellPrice-maxBuyPrice)/abstand,1)
        diskretDiffSells=round((minSellPrice-lastResetMinSellPrice)/abstand,1)
        diskretDiffBuys=round((lastResetMaxBuyPrice-maxBuyPrice)/abstand,1)
        print "diskretDiffSells=",diskretDiffSells,"diskretDiffBuys=",diskretDiffBuys
        minDiff=min(diskretDiffSells,diskretDiffBuys)
        print "estimateProfit(mBTC)=",estimateProfit(diskretDiffSells, diskretDiffBuys, abstand, ghsPkg)
        maxDiff=max(diskretDiffSells,diskretDiffBuys)
        tickerLast=float(ticker['last'])
        discreteDiffSell2Ticker=round((minSellPrice-tickerLast)/abstand,1)
        discreteDiffBuy2Ticker=round((tickerLast-maxBuyPrice)/abstand,1)
        if (minDiff>20): # or maxDiff>130):
                print "Reset Normalization Cycle"
                newCycle=normalizeCycles
                logToken=";minSellPrice;"+strRound(minSellPrice,8)+"\
                ;maxBuyPrice;"+strRound(maxBuyPrice,8)+"\
                ;diskretDiffSells;"+strRound(diskretDiffSells,8)+"\
                ;diskretDiffBuys;"+strRound(diskretDiffBuys,8)+"\
                ;sell2Ticker;"+strRound(discreteDiffSell2Ticker,8)+"\
                ;Ticker2buy;"+strRound(discreteDiffBuy2Ticker,8)+"\
                ;;"        
                logging.info(logToken)
        print "sell2Ticker=",discreteDiffSell2Ticker,"Ticker2buy=",discreteDiffBuy2Ticker
            
        if newCycle>0 and beginningNormalize:
            print "Normalization Cycle"
            newCycle=newCycle-1
            if buyCount>0:
                while maxBuyPrice+abstand<=float(ticker['bid']):                    
                    maxBuyPrice=maxBuyPrice+abstand
                    print "add inner Buys @",maxBuyPrice
                    demo.place_order('buy',ghsPkg,maxBuyPrice)                
                    buyBook=buyBook-((maxBuyPrice+abstand)*ghsPkg)
                    buyCount=buyCount+1
                    buyAdd=buyAdd+1                    
                    ticker = demo.ticker()
                lastResetMaxBuyPrice=maxBuyPrice
         
                while buyCount<=securityMargin:
                    print "add outer Buys"
                    demo.place_order('buy',ghsPkg,minBuyPrice-abstand)
                    minBuyPrice=minBuyPrice-abstand
                    buyCount=buyCount+1
                    
            else:
                print "place single buy"
                highestValue2Buy=minSellPrice
                ticker = demo.ticker()
                while highestValue2Buy+abstand>float(ticker['bid']):
                    highestValue2Buy=highestValue2Buy-abstand
                print "place buy @",highestValue2Buy   
                demo.place_order('buy',ghsPkg,highestValue2Buy) 
                
       
        
            while minSellPrice-abstand>=float(ticker['ask']):                
                minSellPrice=minSellPrice-abstand
                print "place inner sells @",minSellPrice
                demo.place_order('sell',ghsPkg,minSellPrice)            
                sellBook=sellBook+((minSellPrice-abstand)*ghsPkg)
                sellCount=sellCount+1
                sellAdd=sellAdd+1                
                ticker = demo.ticker()
            lastResetMinSellPrice=minSellPrice
    
            while sellCount<=securityMargin:
                print "place outer sells"
                demo.place_order('sell',ghsPkg,maxSellPrice+abstand)
                maxSellPrice=maxSellPrice+abstand        
                sellCount=sellCount+1
                
        
            
        bal = demo.balance()
        time.sleep(1)
        ghs_avl=getFromBal('GHS','available')
        ghs_orders=getFromBal('GHS','orders')
        ghs_tot = ghs_avl+ghs_orders    
        btc_avl=getFromBal('BTC','available')
        btc_orders=getFromBal('BTC','orders')
        btc_tot = btc_avl+btc_orders   
        print "ghs_avl=",ghs_avl,"btc_avl=",btc_avl 
        print "ghs_tot=",ghs_tot, "btc_tot",btc_tot
        ticker = demo.ticker()
        fortuneBTC=round(((float(ticker['last']))*ghs_tot)+btc_tot,8)
        print "fortune=",fortuneBTC,"\n"
        if newCycle>0:
             time.sleep(1)
        else:
            time.sleep(30)
    except:
        print "General Exception"
        #raise
        time.sleep(60)
    